package com.neteast.androidclient.contact.domain;

import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.neteast.androidclient.contact.Constant;
import com.neteast.androidclient.contact.R;
import com.neteast.androidclient.contact.activity.MainActivity;
import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;

public class ContactRowManager {
	
	
	private ContactRowManager(){}
	
	private static ArrayList<LinearLayout> phoneRows=new ArrayList<LinearLayout>();
	private static ArrayList<LinearLayout> emailRows=new ArrayList<LinearLayout>();
	private static ArrayList<LinearLayout> imRows=new ArrayList<LinearLayout>();
	private static ArrayList<LinearLayout> locationRows=new ArrayList<LinearLayout>();
	private static Button currentBtn;
	private static PopupWindow customWindow;
	private static PopupWindow currentWindow;
	/**
	 * 
	  * 插入一条新的空白的消息行，此时为可编辑状态
	 * @param context
	 * @param type 行的类型，分别为PHONE、EMAIL、IM、LOCATION
	 * @param root 放置插入行的容器
	 * @param adapter 插入行里面下拉列表需要的适配器
	 * @param customType 
	 * @return
	 */
	public static LinearLayout insertNewBlankRow(final Context context,final int type,
			final TableLayout root,final ArrayAdapter<String> adapter,
			final LinearLayout selectType,final RelativeLayout customType) {
		
		LayoutInflater inflater=LayoutInflater.from(context);
		final LinearLayout row = (LinearLayout) inflater.inflate(R.layout.info_item, null);
		final RowHolder holder=new RowHolder();
		holder.label=(Button) row.findViewById(R.id.info_item_type);
		holder.input=(EditText) row.findViewById(R.id.info_item_input);
		holder.delete=(ImageView) row.findViewById(R.id.info_item_delete);
		holder.add=(ImageView) row.findViewById(R.id.info_item_add);
		holder.label.setText(adapter.getItem(0));
		
		setLabel(context, adapter, customType, selectType, holder);
		setCustomLabel(context, type, adapter, customType);
		
		
		
		int s1 = phoneRows.size();
		int s2 = emailRows.size();
		int s3 = imRows.size();
		int s4 = locationRows.size();
		switch (type) {
		case Constant.MIME_PHONE:
			holder.input.setInputType(EditorInfo.TYPE_CLASS_PHONE);
			holder.input.setHint(R.string.hint_phone_default);
			root.addView(row, 2+s1);
			phoneRows.add(row);
			break;
		case Constant.MIME_EMAIL:
			holder.input.setInputType(EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS);
			holder.input.setHint(R.string.hint_email_default);
			root.addView(row, 4+s1+s2);
			emailRows.add(row);
			break;
		case Constant.MIME_IM:
			holder.input.setInputType(EditorInfo.TYPE_CLASS_TEXT);
			holder.input.setHint(R.string.hint_im_default);
			root.addView(row, 6+s1+s2+s3);
			imRows.add(row);
			break;
		case Constant.MIME_LOCATION:
			holder.input.setInputType(EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE|EditorInfo.TYPE_CLASS_TEXT);
			holder.input.setHint(R.string.hint_location_default);
			root.addView(row, 8+s1+s2+s3+s4);
			locationRows.add(row);
			break;
		}

		holder.add.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				holder.add.setVisibility(View.GONE);
				insertNewBlankRow(context, type, root, adapter, selectType, customType);
			}
		});
		holder.delete.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				root.removeView(row);
				ArrayList<LinearLayout> rows=phoneRows;
				switch (type) {
				case Constant.MIME_PHONE:
					rows=phoneRows;
					break;
				case Constant.MIME_EMAIL:
					rows=emailRows;
					break;
				case Constant.MIME_IM:
					rows=imRows;
					break;
				case Constant.MIME_LOCATION:
					rows=locationRows;
					break;
				}
				rows.remove(row);
				((RowHolder) rows.get(rows.size()-1).getTag()).
					add.setVisibility(View.VISIBLE);
			}
		});
		row.setTag(holder);
		return row;
	}

	private static void setCustomLabel(final Context context, final int type,
			final ArrayAdapter<String> adapter, RelativeLayout customType) {
		
		
		customType.findViewById(R.id.cancel).setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				customWindow.dismiss();
			}
		});
		
		final EditText inText=(EditText) customType.findViewById(R.id.input_type);
		customType.findViewById(R.id.ok).setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				String value = inText.getText().toString();
				if (!TextUtils.isEmpty(value)) {
					currentBtn.setText(value);
					ArrayList<String> localType=MainActivity.phoneTypes;
					switch (type) {
					case Constant.MIME_PHONE:
						localType=MainActivity.phoneTypes;
						break;
					case Constant.MIME_EMAIL:
						localType=MainActivity.emailTypes;
						break;
					case Constant.MIME_IM:
						localType=MainActivity.imTypes;
						break;
					case Constant.MIME_LOCATION:
						localType=MainActivity.locationTypes;
						break;
					}
					if (!localType.contains(value)) {
						localType.add(value);
						adapter.notifyDataSetChanged();
					}
					customWindow.dismiss();
				}else {
					Toast.makeText(context, "自定义标签不能为空", Toast.LENGTH_SHORT).show();
					return;
				}
			}
		});
	}
	
	private static void setLabel(final Context context,final ArrayAdapter<String> adapter, 
			final RelativeLayout customType,final LinearLayout selectType,final RowHolder holder) {
		
		final ListView typeList=(ListView) selectType.findViewById(R.id.types);
		final Button label=holder.label;
		final EditText input=holder.input;
		
		label.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				typeList.setAdapter(adapter);
				currentBtn=(Button) v;
				PopupWindow typeListWindow=new PopupWindow(selectType,label.getMeasuredWidth(),300,true);
				typeListWindow.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.bg_dialog));
				currentWindow=typeListWindow;
				typeListWindow.showAsDropDown(v);
			}
		});
		label.addTextChangedListener(new TextWatcher() {
			private String temp;
			public void onTextChanged(CharSequence s, int start, int before, int count) {}
			
			public void beforeTextChanged(CharSequence s, int start, int count,
					int after) {
				temp=s.toString();
			}
			
			public void afterTextChanged(Editable s) {
				if (s.toString().equals("自定义")) {
					label.setText(temp);
				}
			}
		});
		typeList.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
				if (position==4) {
					customWindow = new PopupWindow(customType,input.getMeasuredWidth(),input.getMeasuredWidth()*2/3,true);
					customWindow.setBackgroundDrawable(context.getResources().getDrawable(R.drawable.bg_dialog));
					customWindow.showAsDropDown(currentBtn,currentBtn.getWidth(),-currentBtn.getHeight());
				}
				TextView tv=(TextView) view;
				currentBtn.setText(tv.getText().toString());
				currentWindow.dismiss();
			}
		});
	}
		
	/**
	 * 为空白行填入数据，并把行设置为不可编辑的展示状态
	 * @param row
	 * @param types
	 * @param data
	 */
	public static void fillRowWithContent(LinearLayout row, ContactData data) {
		RowHolder holder=(RowHolder) row.getTag();
		holder.add.setVisibility(View.GONE);
		holder.delete.setVisibility(View.GONE);
		holder.label.setEnabled(false);
		holder.input.setEnabled(false);
		holder.label.setText(data.label);
		holder.input.setText(data.content);
		holder.id=data.id;
		holder.isReadOnly=data.isReadOnly;
		holder.localId=data.localId;
		holder.mimeTypeId=data.mimeTypeId;
	}
	
	public static class RowHolder{
		int id;
		int localId;
		boolean isReadOnly;
		Button label;
		EditText input;
		ImageView delete;
		ImageView add;
		int mimeTypeId;
	}
	/**
	 * 使得每行变得可编辑
	 */
	public static void setRowsEditable() {
		setRowsEditable(phoneRows,MainActivity.phoneTypes);
		setRowsEditable(emailRows,MainActivity.emailTypes);
		setRowsEditable(imRows,MainActivity.imTypes);
		setRowsEditable(locationRows,MainActivity.locationTypes);
	}
	/**
	 * 使得每行变得可编辑，并且，只有某类最后一行才出现+号
	 * @param rows
	 * @param phoneTypes 
	 */
	private static void setRowsEditable(ArrayList<LinearLayout> rows, ArrayList<String> types) {
		int size=rows.size();
		for(int i=0;i<size;i++){
			LinearLayout row = rows.get(i);
			RowHolder holder=(RowHolder) row.getTag();
			if (!holder.isReadOnly) {
				holder.label.setEnabled(true);
				holder.input.setEnabled(true);
				holder.delete.setVisibility(View.VISIBLE);
			}
			if (i==size-1) {
				holder.add.setVisibility(View.VISIBLE);
			}
		}
	}
	
	public static void closeRowsEditable(TableLayout container,Contact data) {
		closeRowsEditable(container,phoneRows, data.phones);
		closeRowsEditable(container,emailRows, data.emails);
		closeRowsEditable(container,imRows, data.ims);
		closeRowsEditable(container,locationRows, data.locations);
	}
	
	private static void closeRowsEditable(TableLayout container,ArrayList<LinearLayout> rows,ArrayList<ContactData> data) {
		int size=rows.size();
		ContactData contactData;
		for(int i=0;i<size;i++){
			LinearLayout row = rows.get(i);
			RowHolder holder=(RowHolder) row.getTag();
			if (!holder.isReadOnly) {
				holder.label.setEnabled(false);
				holder.input.setEnabled(false);
				holder.delete.setVisibility(View.GONE);
			}
			holder.add.setVisibility(View.GONE);
			String value = holder.input.getText().toString();
			if (TextUtils.isEmpty(value)) {
				container.removeView(row);
				rows.remove(row);
				size--;
				i--;
			}else {
				contactData=new ContactData();
				contactData.id=holder.id;
				contactData.label=holder.label.getText().toString();
				contactData.content=holder.input.getText().toString();
				contactData.isReadOnly=holder.isReadOnly;
				contactData.localId=holder.localId;
				contactData.mimeTypeId=holder.mimeTypeId;
				data.add(contactData);
			}
		}
	}
	
	public static JSONObject isContactChanged(Contact cold,Contact cNew){
		try {
			Log.i("test", "old="+cold);
			Log.i("test", "new="+cNew);
			boolean isChanged=false;
			JSONObject object=new JSONObject();
			object.put("ownId", cold.ownId);
			object.put("contactId", cold.contactId);
			object.put("isReadOnly", cold.isReadOnly);
			
			if (!cold.isReadOnly) {
				if (!cNew.displayName.equals(cold.displayName)) {
					isChanged=true;
					object.put("displayName", cNew.displayName);
				}
				
				if (!cNew.nickName.equals(cold.nickName)) {
					isChanged=true;
					object.put("nickName", cNew.nickName);
				}
				
				if (!cNew.organization.equals(cold.organization)) {
					isChanged=true;
					object.put("organization", cNew.organization);
				}
				
				if (!cNew.job.equals(cold.job)) {
					isChanged=true;
					object.put("job", cNew.job);
				}
				
				if (cNew.hasPhoto&&!cNew.photo.equals(cold.photo)) {
					isChanged=true;
					object.put("photo", cNew.photo);
				}
				
				if (cNew.hasPhoto!=cold.hasPhoto) {
					isChanged=true;
					object.put("hasPhoto", cNew.hasPhoto);
				}
				
				if (!cNew.state.equals(cold.state)) {
					isChanged=true;
					object.put("state", cNew.state);
				}
			}
			
			
			if (!cNew.groups.equals(cold.groups)) {
				isChanged=true;
				object.put("groups", cNew.groups);
			}
			
			if (!cNew.remark.equals(cold.remark)) {
				isChanged=true;
				object.put("remark", cNew.remark);
			}
			
			JSONArray array = compareContactData(cold.phones, cNew.phones);
			if (array.length()>0) {
				isChanged=true;
				object.put("phones", array);
			}
			array = compareContactData(cold.emails, cNew.emails);
			if (array.length()>0) {
				isChanged=true;
				object.put("emails", array);
			}
			array = compareContactData(cold.ims, cNew.ims);
			if (array.length()>0) {
				isChanged=true;
				object.put("ims", array);
			}
			array = compareContactData(cold.locations, cNew.locations);
			if (array.length()>0) {
				isChanged=true;
				object.put("locations", array);
			}
			if (isChanged) {
				return object;
			}
		} catch (Exception e) {
			Log.e("test", e.getMessage(),e);
		}
		return null;
	}
	
	private static JSONArray compareContactData(ArrayList<ContactData> oldPhones, ArrayList<ContactData> newPhones)throws JSONException {
		JSONArray array=new JSONArray();
		JSONObject jsonObject;
		int countI=oldPhones.size();
		int countJ=newPhones.size();
		int i=0;
		int j=0;
		for (;i<countI&&j<countJ; i++,j++) {
			ContactData oldData = oldPhones.get(i);
			ContactData newData = newPhones.get(j);
			if (oldData.isReadOnly) {
				continue;
			}
			if (!oldData.equals(newData)) {
				jsonObject=new JSONObject();
				jsonObject.put("id", oldData.id);
				jsonObject.put("label", newData.label);
				jsonObject.put("content", newData.content);
				jsonObject.put("isReadOnly", newData.isReadOnly);
				jsonObject.put("modified", Constant.CONTACT_UPDATE);
				array.put(jsonObject);
			}
		}
		if (countI<countJ) {
			for (;j<countJ;j++){
				jsonObject=new JSONObject();
				ContactData data = newPhones.get(j);
				jsonObject.put("label", data.label);
				jsonObject.put("content", data.content);
				jsonObject.put("isReadOnly", data.isReadOnly);
				jsonObject.put("modified", Constant.CONTACT_NEW);
				array.put(jsonObject);
			}
		}else if (countI>countJ) {
			for (;i<countI;i++){
				jsonObject=new JSONObject();
				ContactData data = oldPhones.get(i);
				jsonObject.put("id", data.id);
				jsonObject.put("modified", Constant.CONTACT_DELETE);
				array.put(jsonObject);
			}
		}
		return array;
	}
	public static void clearRowsCache(){
		phoneRows.clear();
		emailRows.clear();
		imRows.clear();
		locationRows.clear();
	}
}
